package com.xwaiy.xwaiyrpc.fault.retry;

import com.github.rholder.retry.*;
import com.xwaiy.xwaiyrpc.model.RpcResponse;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 指数退避重试策略
 * @Author Xwaiy
 * @Date 2025/9/3 15:28
 **/
@Slf4j
public class ExponentialBackoffRetryStrategy implements RetryStrategy{
    @Override
    public RpcResponse doRetry(Callable<RpcResponse> callable) throws Exception {
        Retryer<RpcResponse> retryer = RetryerBuilder.<RpcResponse> newBuilder()
                .retryIfException()
                .withWaitStrategy(WaitStrategies.exponentialWait(1000,30000, TimeUnit.MILLISECONDS))
                .withStopStrategy(StopStrategies.stopAfterAttempt(5))
                .withRetryListener(new RetryListener(){

                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        log.info("第{}次重试，延迟时间会根据策略变化",attempt.getAttemptNumber());
                    }
                })
                .build();

        try {
            return retryer.call(callable);
        } catch (ExecutionException e) {
            throw new Exception("重试失败", e.getCause());
        } catch (RetryException e) {
            throw new Exception("重试次数已达上限");
        }
    }
}
